package com.qianfeng.iot.driver.service.impl;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import cn.hutool.core.lang.UUID;
import com.dc3.common.model.Driver;
import com.qianfeng.iot.driver.service.DriverService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.Query;
import org.springframework.data.relational.core.query.Update;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * Created by Jackiechan on 2022/8/9 20:34
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */

@Service
public class DriverServiceImpl implements DriverService {
    private R2dbcEntityTemplate r2dbcEntityTemplate;


    @Autowired
    public void setR2dbcEntityTemplate(R2dbcEntityTemplate r2dbcEntityTemplate) {
        this.r2dbcEntityTemplate = r2dbcEntityTemplate;
    }

    @Override
    public Mono<Driver> addDriver(Driver driver) {
        //先查询数据是不是已经存在, 如果是存在就检查状态,如果是删除状态,则更新为非删除
        //当然是不是允许重复数据属于我们的业务上的要求,如果不允许重复就先检查是不是存在,如果允许重复我们就不管检查,直接添加数据
        //假如我们的业务要求可以重复,也就是一个驱动可以有多个服务,甚至多个服务的名字也可以一样
        driver.setId(UUID.randomUUID().toString(true));
        return r2dbcEntityTemplate.insert(Driver.class).into("dc3_driver").using(driver);
        //我们发现需要在这里添加其他数据,包括驱动属性和位号属性,但是不一定都有数据有可能只有位号属性,有可能只有驱动属性
        //我们要添加驱动属性或者是位号属性需要首先得到一个驱动的id,也就是在当前的添加操作之后
        //但是我们当前的添加会存在一些特殊情况,我们相同的驱动如果添加多个机器我们现在的处理措施是添加多条数据,
        //那么与之对应的就是每一个驱动id都应该对应一些属性或者位号,但是如果我只是重复启动了一个驱动,那么我们现在是没有进行区分的
        //所以即便是我们重复启动一个驱动,会产生多条驱动数据,那就会导致与之前启动绑定的属性失效了,那那些数据还有什么用?
        //经过分析,我们的驱动的数据和驱动相关的数据来自于驱动程序,它可以在启动的时候将数据通过mq传递到我们的manager服务,manager
        //会远程调用我们当前的功能添加数据,并且到添加后的id,然后在manager中通过结果获取到驱动的id,然后再根据其他的数据决定是否添加其他数据
    }

    @Override
    public Mono<Integer> updateDriver(Driver driver) {
        return r2dbcEntityTemplate.update(Driver.class).inTable("dc3_driver")
                .matching(Query.query(Criteria.where("id").is(driver.getId())
                        //我们的要求是删除的数据不可以更新,所以更新的条件中带有这个删除
                        .and(Criteria.where("deleted").is(0))
                        .and(Criteria.where("tenant_id").is(driver.getTenantId())))).apply(
                        Update.update("host", driver.getHost())
                                .set("port", driver.getPort())
                                .set("description", driver.getDescription())
                                .set("update_time", driver.getUpdateTime()));

    }

    @Override
    public Mono<Integer> deleteByIds(List<String> ids, String tenantId) {
        return r2dbcEntityTemplate.update(Driver.class).inTable("dc3_driver")
                .matching(Query.query(Criteria.where("id").in(ids)
                        .and(Criteria.where("tenant_id").is(tenantId)))).apply(
                        Update.update("deleted", 1));
    }

    @Override
    public Mono<Driver> findById(String id, String tenantId) {
        return r2dbcEntityTemplate.select(Driver.class).from("dc3_driver")
                .matching(Query.query(Criteria.where("id").is(id)
                                .and(Criteria.where("deleted").is(0))
                .and(Criteria.where("tenant_id").is(tenantId)))).first();
    }
}
